<template>
	<view class="container">
		<!-- 自定义导航栏 start -->
		<view class="header-board">
			<view @click="onIconBtnClick('back')" class="back-img"><image src="../../../static/images/common/close.png" /></view>
			<view class="back-img" @click="onIconBtnClick('collect')"><image src="@/static/images/common/collect.png" /></view>
		</view>
		<!-- 自定义导航栏 end -->

		<!-- 背景图 start -->
		<view class="back-board"><image src="@/static/images/common/play_bg.png" /></view>
		<!-- 背景图 end -->

		<!-- 播放区域 start -->
		<view class="play-board">
			<!-- 音频背景图片 start -->
			<view class="cover-img"><image class="img" :src="playParams.imgUrl"></image></view>
			<!-- 音频背景图片 end -->

			<!-- 音频名称 start -->
			<view class="play-title">{{ playParams.title || '未命名音频' }}</view>
			<!-- 音频名称 end -->

			<!-- 播放控制区域 start -->
			<view class="play-icons-board">
				<view data-action="down" class="down-icon" @click="onProgressControl"><image src="@/static/images/audio/down.png" /></view>
				<view class="middle-icon-board" @click="onAudioClick">
					<image src="@/static/images/audio/wrap.png" />
					<view class="play-status" :class="!isPlaying ? 'start' : ''">
						<image :src="isPlaying ? require('@/static/images/audio/pause.png') : require('@/static/images/audio/start.png')" />
					</view>
				</view>
				<view data-action="up" class="up-icon" @click="onProgressControl"><image src="@/static/images/audio/up.png" /></view>
			</view>
			<!-- 播放控制区域 end -->

			<!-- 滑动区域 start -->
			<movable-area  id="J-slider" class="play-progress-board" @click="onProgressControl">
				<view class="line" :style="{width:audioProgress+'%'}">
					<movable-view  :x="musicProgress" class="dot" direction="horizontal" @htouchmove="onSliderTouchMove" @change="onSliderChange" >
						{{ currentTime | formatTime }} / {{ audioDuration | formatTime }}
					</movable-view>
				</view>
			</movable-area>
			<!-- 滑动区域 end -->

			<!-- 音频功能区域 start -->
			<view class="play-func-board">
				<view :key="index" v-for="(item, index) in playModes" class="func-img" @click="onPlayModeControl" :data-action="item.field">
					<image :src="item[item.field === playMode ? 'selected_url' : 'url']" />
				</view>
			</view>
			<!-- 音频功能区域 end -->
		</view>
		<!-- 播放区域 end -->

		<!-- 播放列表区域 start -->
		<Playlist :isShow="showPlayList" :title="formatPlayModes" :lists="playList.lists" :curIdx="playList.curIdx" @click="onPlayListClick" @close="onPlayModeControl"></Playlist>

		<!-- 播放列表区域 end -->
		
		<loading></loading>
	</view>
</template>

<script>
import tools from '../../../utils/tools.js';
import Playlist from '@/component/playlist/playlist.vue';
import { throttle } from '../../../utils/utils.js';
import { formatTime, formatPlayMode } from '../../../utils/filter.js';
import { play_mode_icons, play_modes, RECODE_MAX_LIMIT } from '@/config/play';
import { TOPIC, OPEARTION_TYPE, COLLECT_TYPE } from '../../../config/topic.js';
export default {
	components: { Playlist },
	data() {
		return {
			playModes: play_mode_icons,
			playMode: play_modes.LOOP,
			playParams: {},
			datalist: {},

			audioManager: null,
			isPlaying: false,
			isCollect: false,
			currentTime: 0,
			sliderPos: {},

			playList: {
				lists: [],
				total: 0,
				curIdx: 0
			},
			playRecord: [],
			topic: 'music',
			audioDuration: '',
			sliderHeight: 0,

			// 延迟改变滑块进度
			delayTime: null,
			// 是否是手动拖动滑块
			isSliderChange: false,
			audioProgress: 0,
			showPlayList: false
		};
	},
	filters: {
		formatTime,
		formatPlayMode
	},
	computed: {
		musicProgress: function() {
			const { sliderHeight, audioProgress } = this.$data;
			

			let result=sliderHeight * audioProgress / 100;
			return result
		},
		formatPlayModes: function() {
			return formatPlayMode(this.playMode);
		}
	},

	onReady() {
		this.getMustInfo();
		this.initPlayAudio();
		// 获取滑块相关属性
		this.getSliderProperty();
		// 查询收藏状态
		// this.searchCollectStatus(playParams.id);
		
	},
	methods: {
		 getMustInfo() {
			const { playParams, playList, playRecord } =this.$store.state;
			console.log(this.$store.state);
			this.playParams = playParams;
			this.playList = playList;
			this.playRecord = playRecord;
		},

		/**
		 * @description 列表点击事件
		 * @param {object} e - 事件源
		 * @returns {void}
		 */
		onPlayListClick: throttle(
			function(e) {
				// const { data: { index, id: newId } } = e.data;
				const data = { index: e.data.index, newId: e.data.id };
				const { id } = this.playParams;

				if (id === data.newId) {
					console.log('禁止切换当前音乐.');
					return;
				}

				const { lists } = this.playList;

				// 提交数据
				this.$store.commit('changeState', {
					playList: {
						...this.playList,
						curIdx: data.index
					},
					playParams: lists[data.index]
				});

				// 隐藏播放列表
				this.showPlayList = false;
				this.getMustInfo();

				// 清除音频实例
				this.clearPlayManager();
				// 播放选中音频
				this.initPlayAudio();
			},
			300,
			false
		),

		/**
		 * @description 查询收藏状态
		 * @param {number} id - 音频ID
		 * @returns {void}
		 */
		async searchCollectStatus(id) {
			const collectType = COLLECT_TYPE.SINGLE;

			const {
				result: { data }
			} = await this.getCollectStatus(collectType, id);

			// this.setData({
			//   ...data
			// });
		},

		/**
		 * @description 查询收藏状态
		 * @param {string} collectType - 收藏类型
		 * @param {string} id - 主题ID
		 * @returns {promise}
		 */
		getCollectStatus(collectType, id) {
			const { openid } = storage.get('user');
			return wx.cloud.callFunction({
				name: 'service',
				data: {
					action: 'queryCollectStatus',
					data: {
						collectType,
						openid,
						id
					}
				}
			});
		},

		/**
		 * @description 播放模式控制
		 * @param {object} e - 事件源
		 * @returns {void}
		 */
		onPlayModeControl(e) {
			const { action } = e.currentTarget ? tools.getEventDetail(e) : e;

			// const { action } = tools.getEventDetail(e)||e;

			switch (action) {
				case 'timing':
					console.log('定时播放');
					break;
				case 'single':
				case 'loop':
					this.playMode = action;

					break;
				case 'playlist':
					// 打开播放列表
					this.showPlayList = true;

					break;
				case 'close':
					// 关闭播放列表
					this.showPlayList = false;
					break;
				default:
					console.log('no matching entries.');
					break;
			}
		},

		/**
		 * @description 音频进度控制
		 * @param {object} e - 事件源
		 * @returns {void}
		 */
		onProgressControl: throttle(
			function(e) {
				const { action } = e.currentTarget.dataset;
				const { audioManager, currentTime, audioDuration } = this.$data;

				switch (action) {
					case 'down':
						// 后退15s
						let prevTime = currentTime - 15;
						if (prevTime < 0) {
							prevTime = 0;
						}
						audioManager.seek(prevTime);
						break;
					case 'up':
						// 前进15s
						let nextTime = currentTime + 15;
						if (nextTime >= audioDuration) {
							nextTime = audioDuration;
						}
						audioManager.seek(nextTime);
						break;
					default:
						console.log('no matching entries.');
						break;
				}
			},
			200,
			false
		),

		onIconBtnClick(name) {
			console.log(111);
			if (name == 'back') {
				uni.navigateBack({
					delta: 1
				});
			} else if (name == 'collect') {
			}
		},

		onSliderChange(e) {
			if (this.delayTime) {
				clearTimeout(this.delayTime);
			}
			// 如果非触摸状态
			if (!this.isSliderChange) return;

			this.delayTime = setTimeout(() => {
				const { sliderHeight, audioDuration, audioManager } = this.$data,
					{ x } = e.detail;
					console.log(x);
				const curTime = audioDuration * (x / sliderHeight).toFixed(2);	
				console.log(curTime);

				audioManager && audioManager.seek(curTime);

				this.isSliderChange = false;
			}, 300);
		},

		/**
		 * @description 滑块首次触摸
		 * @returns {void}
		 */
		onSliderTouchMove() {
			console.log('onSliderTouchMove');
			this.isSliderChange = true;
		},
		/**
		 * @description 获取滑块长度
		 * @returns {void}
		 */
		getSliderProperty() {
			const query = uni.createSelectorQuery().in(this);
			query.select('#J-slider').boundingClientRect(res => {
			 	const { width } = res;
			 	this.sliderHeight = width;
			}).exec();
			
		},

		onAudioClick() {
			const { isPlaying, audioManager } = this.$data;

			audioManager && audioManager[isPlaying ? 'pause' : 'play']();
			this.isPlaying = !this.isPlaying;
		},
		clearPlayManager() {
			this.currentTime = 0;
			this.audioManager = null;
		},
		playNextAudio() {
			var playMode = this.playMode;
			const restartPlayAudio = () => {
				setTimeout(() => {
					// 重新播放音频
					this.initPlayAudio();
				}, 500);
			};

			switch (playMode) {
				case 'single':
					// 延迟播放音频
					restartPlayAudio();
					break;
				case 'loop':
					// 处理循环播放
					processLoopAudio.call(this);
					break;
			}

			function processLoopAudio() {
				let { total, curIdx, lists } = this.playList;

				if (!total) return;

				curIdx < total - 1 ? curIdx++ : (curIdx = 0);

				// 提交数据
				this.$store.commit('changeState', {
					playList: {
						...this.data.playList,
						curIdx: curIdx
					},
					playParams: lists[curIdx]
				});

				// 延迟播放音频
				restartPlayAudio();
			}
		},

		/**
		 * @description 缓存播放记录
		 * @returns {void}
		 */
		//   recordAudio () {
		//     const { playParams, playRecord } = this.data,
		//           { topic, type } = this.$store.state,
		//           total = playRecord.length;

		//     // 移除已经存在数据
		//     const recordIdx = playRecord.findIndex(item => item.id === playParams.id);
		//     if (!!~recordIdx) {
		//       playRecord.splice(recordIdx, 1);
		//     }

		//     // 添加新数据
		//     playRecord.push(
		//       Object.assign({ topic, type }, playParams)
		//     );

		//     // 限制缓存音频数量
		//     if (total > RECODE_MAX_LIMIT) {
		//       playRecord.splice(0, 1);
		//     }

		//     // 提交数据
		//     this.$store.commit('changeState', {
		//       playRecord
		//     });
		//   },

		/**
		 * @description 初始化音频播放器
		 * @returns {void}
		 */
		initPlayAudio() {
			if (this.audioManager) return this.audioManager.play();

			const audioManager = uni.createInnerAudioContext();
			this.audioManager = audioManager;

			// 初始化音频事件监听
			this.initAudioListeners(audioManager);

			// this.initMusicAudio(audioManager);

			const { topic } = this.$data;

			switch (topic) {
				case TOPIC.MUSIC:
					// 播放音乐
					this.initMusicAudio(audioManager);
					break;
				case TOPIC.STORY:
					// 播放故事
					// this.initStoryAudio(audioManager);
					break;
				default:
					break;
			}
		},
		async initMusicAudio(audioManager) {
			const { id, title, author, imgUrl } = this.playParams;
			this.$store.commit('startLoading')
			const { result } = await uniCloud.callFunction({
				name: 'music',
				data: {
					action: 'url',
					field: id,
					limit: 15
				}
			});
			console.log(result);
			this.$store.commit('endLoading')
			
			const {
				code,
				message,
				data: { url }
			} = result;

			if (code === 0 && url) {
				return this.playAudio({
					 audioManager,
					      title,
					      author,
					      imgUrl,
					      url
				});
			}

			const { total } = this.playList;

			if (total) {
				// 1. 清除旧音频实例
				this.clearPlayManager();
				// 2. 播放下一段音频
				this.playNextAudio();
				return;
			}
		},
		playAudio({ audioManager, url }) {
			audioManager.autoplay = true;
			audioManager.src = url;
			audioManager.onPlay(() => {
				console.log('开始播放');
				this.isPlaying = true;
			});
			// this.audioManager=audioManager

			// 循环换取音频总长度（获取音频有延迟）
			let getDurationTimer = setInterval(() => {
				const totalTime = audioManager.duration;

				if (typeof totalTime === 'number' && totalTime) {
					clearInterval(getDurationTimer);
					// 1. 设置音频长度
					this.audioDuration = Math.round(totalTime);
					// 2. 缓存播放记录
					// this.recordAudio();
				}
			}, 300);
		},

		initAudioListeners(audioManager) {

				// audioManager.autoplay = true;
				audioManager.onPlay(() => {
					console.log('[audio]：', 'onPlay');
					this.isPlaying = true;
				});

				['onPause', 'onStop', 'onError', 'onEnded'].forEach(method => {
					audioManager &&
						audioManager[method](reason => {
							this.isPlaying = false;

							if (method === 'onEnded') {
								// 1. 清除旧音频实例
								this.clearPlayManager();
								// 2. 播放下一段音频
								this.playNextAudio();
							}
						});
				});

			// 音频播放进度更新
			audioManager.onTimeUpdate(() => {
				const { audioManager, audioDuration, currentTime } = this.$data;

				if (audioManager && audioDuration) {
					const current = Math.floor(audioManager.currentTime);

					if (current === currentTime) return;
					if (this.isSliderChange) return;

					this.currentTime = current;
					this.audioProgress = Math.floor((current / audioDuration) * 100);
				}
			});
		}
	}
};
</script>

<style lang="scss">
.container {
	// height: 200vh;
	overflow: scroll;
	height: auto;
	box-sizing: border-box;
	margin-top: 100rpx;
}

.header-board {
	position: fixed;
	z-index: 200;
	display: flex;
	align-items: center;
	width: 100%;
	height: 100rpx;
	margin-top: 50rpx;
}

.header-board .back-img,
.header-board .collect-img {
	width: 100rpx;
	height: 100rpx;
	margin-left: 40rpx;
	border-radius: 50%;
	overflow: hidden;
}

.back-board {

	position: fixed;
	top: 0;
	left: 0;
	z-index: 1;
	width: 100%;
	height: 100%;
}

.play-board {
	// margin-top: 160rpx;
	display: flex;
	flex-direction: column;
	align-items: center;
	position: fixed;
	width: 100%;
	height: 100%;
	z-index: 2;
}

.play-board .cover-img {
	position: relative;
	width: 508rpx;
	height: 414rpx;
	margin: 241rpx 121rpx 0 121rpx;
	background-color: #d8d8d8;
	opacity: 0.7;
	border-radius: 20rpx;
	box-shadow: 0rpx 46rpx 30rpx -36rpx rgba(80, 140, 46, 0.4);
	overflow: hidden;
}

.play-board .play-title {
	width: 100%;
	height: 38rpx;
	margin-top: 64rpx;
	text-align: center;
	font-size: 38rpx;
	font-weight: 500;
	color: #e6e7f2;
	box-sizing: border-box;
}

.play-board .play-icons-board {
	display: flex;
	flex-direction: row;
	justify-content: space-around;
	align-items: center;
	margin-top: 80rpx;
	width: 80%;
	height: 218rpx;
}

.play-board .play-icons-board .down-icon,
.play-board .play-icons-board .up-icon {
	width: 66rpx;
	height: 66rpx;
}

.play-board .play-icons-board .middle-icon-board {
	display: flex;
	justify-content: center;
	align-items: center;
	position: relative;
	width: 148rpx;
	height: 148rpx;
}

.play-board .play-icons-board .middle-icon-board .play-status {
	position: absolute;
	width: 28rpx;
	height: 38rpx;
	text-align: center;
}

.play-board .play-icons-board .middle-icon-board .play-status.start {
	margin-left: 5rpx;
}

.play-board .play-progress-board {
	margin-top: 55rpx;
	width: 600rpx;
	height: 3rpx;
	border-radius: 50rpx;
	background-color: #47557e;
}

.play-board .play-progress-board .line {
	position: relative;
	width: 0%;
	height: 100%;
	background-color: #e6e7f2;
}

.play-board .play-progress-board .line .dot {
	position: absolute;
	top: -20rpx;
	right: 0;
	width: 156rpx;
	height: 44rpx;
	line-height: 44rpx;
	text-align: center;
	background-color: #8e97fd;
	border-radius: 22rpx;
	font-size: 22rpx;
	font-family: PingFangSC, PingFangSC-Regular;
	font-weight: 400;
	color: #e6e7f2;
}

.play-board .play-func-board {
	// position: relative;
	z-index: 100;
	display: flex;
	flex-direction: row;
	justify-content: space-between;
	align-items: center;
	margin-top: 77rpx;
	width: 600rpx;
	height: 130rpx;
}

.play-board .play-func-board .func-img {
	width: 66rpx;
	height: 66rpx;
	image {
		width: 100%;
		height: 100%;
	}
}
</style>
